//AudioMgr.ts
import { Node, AudioSource, AudioClip, resources, director, isValid } from 'cc';
import { BaseMgr } from '../base/BaseMgr';
/**
 * @en
 * this is a sington class for audio play, can be easily called from anywhere in you project.
 * @zh
 * 这是一个用于播放音频的单件类，可以很方便地在项目的任何地方调用。
 */
export class AudioMgr extends BaseMgr {
	public static get inst() {
		return this.getInstance();
	}
	private _audioSource: AudioSource;
	constructor() {
		super();
		//@en create a node as audioMgr
		//@zh 创建一个节点作为 audioMgr
		let audioMgr = new Node();
		audioMgr.name = '__audioMgr__';

		//@en add to the scene.
		//@zh 添加节点到场景
		director.getScene().addChild(audioMgr);

		//@en make it as a persistent node, so it won't be destroied when scene change.
		//@zh 标记为常驻节点，这样场景切换的时候就不会被销毁了
		// director.addPersistRootNode(audioMgr);

		//@en add AudioSource componrnt to play audios.
		//@zh 添加 AudioSource 组件，用于播放音频。
		this._audioSource = audioMgr.addComponent(AudioSource);

	}

	public get audioSource() {
		return this._audioSource;
	}


	/** 通过id播放背景音乐 */
	playById: (audioId: number, volume?: number) => void;
	/** 通过id播放 */
	playOneShotById: (audioId: number, volume?: number) => void;

	/**
	 * @en
	 * play short audio, such as strikes,explosions
	 * @zh
	 * 播放短音频,比如 打击音效，爆炸音效等
	 * @param sound clip or url for the audio
	 * @param volume 
	 */
	playOneShot(sound: AudioClip | string, volume: number = 1.0) {
		if (sound instanceof AudioClip) {
			this._audioSource.playOneShot(sound, volume);
		}
		else {
			resources.load(sound, (err, clip: AudioClip) => {
				if (err) {
					console.log(err);
				}
				else {
					this._audioSource.playOneShot(clip, volume);
				}
			});
		}
	}

	/**
	 * @en
	 * play long audio, such as the bg music
	 * @zh
	 * 播放长音频，比如 背景音乐
	 * @param sound clip or url for the sound
	 * @param volume 
	 */
	play(sound: AudioClip | string, volume: number = 1.0) {
		if (sound instanceof AudioClip) {
			this._audioSource.clip = sound;
			this.audioSource.volume = volume;
			this._audioSource.play();
		}
		else {
			resources.load(sound, (err, clip: AudioClip) => {
				if (err) {
					console.log(err);
				}
				else {
					if (!isValid(this._audioSource)) return;
					if (this._audioSource.playing) {
						this._audioSource.stop()
					}
					this._audioSource.clip = clip;
					this._audioSource.play();
					this._audioSource.loop = true;
					this.audioSource.volume = volume;
				}
			});
		}
	}

	/**
	 * stop the audio play
	 */
	stop() {
		this._audioSource.stop();
	}

	/**
	 * pause the audio play
	 */
	pause() {
		this._audioSource.pause();
	}

	/**
	 * resume the audio play
	 */
	resume() {
		this._audioSource.play();
	}
}